/*
 * Copyright 2009 Fredrik Bridell  
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */

package com.bridell.punity;

/**
 * The TestResult is what it sounds like, it's the result of a test. 
 * It stores various data about the test, including, of course, 
 * whether or not it passed or not. (To "pass" a test is to test 
 * something and have that test return true).
 * @author Fredrik Bridell
 *
 */
public class TestResult {
	private boolean passed = false; 
	private String comment; 
	private Comparable<?> expected;
	private Comparable<?> actual;
	private TestType testType;
	private int counter; 
	private String label;
	
	/**
	 * Constructor. 
	 * @param passed    whether the test was succesful (true) or not (false)
	 * @param testType  One of the TestType enum values
	 * @param expected  The expected value
	 * @param actual    The actual value
	 * @param label     The "label" of the test, used to identify tests
	 * @param comment   Optional comment about the test
	 * @param counter   Incremental counter used along with label to identify a test
	 */
	public TestResult(boolean passed, 
			TestType testType, 
			Comparable<?> expected, Comparable<?> actual, 
			String label, String comment, int counter){
		this.passed = passed;
		this.testType = testType;
		this.expected = expected;
		this.actual = actual;
		this.label = label;
		this.comment = comment;
		this.counter = counter; 
	}
		
	/**
	 * Tests whether this test passed
	 * @return  true if the test passed, else false
	 */
	public boolean passed() {
		return passed;
	}

	/**
	 * @return the actual value that was tested
	 */
	public Comparable<?> getActual() {
		return actual;
	}
	
	/**
	 * Gets the comment for the test. Comments are just strings that help you identify a certain test.
	 * @return  the comment associated with this test
	 */
	public Comparable<?> getComment() {
		return comment;
	}

	/**
	 * Gets the expected value. Typically you are testing that a value is what you expect.
	 * @return  the expected value that was tested for
	 */
	public Comparable<?> getExpected() {
		return expected;
	}

	/**
	 * Gets the value of the incremental counter that helps you identify a test.
	 * The counter is mainly used to identify results that have no comment 
	 * Note however that the counter is reset to 1 whenever the label is set. 
	 * This can lead to unexpected results if you set the label to the same 
	 * value several times.
	 * @return  the counter value for this test.
	 */
	public int getCounter(){
		return counter;
	}

	/**
	 * Gets the id of this test
	 * @return  the id string, comprised of the label, a hash sign (#) and the counter
	 * value at the time the test was performed. If the label was not set it is an 
	 * empty string so the ID is just the counter. 
	 */
	public String getID() {
		return label + "#" + counter;
	}


	/**
	 * Gets the test type for this test.
	 * @return  The test type, one of the TestType enum values (TestType.EQUALS, etc)
	 */
	public TestType getTestType() {
		return testType;
	}
	
	/**
	 * Returns a human-readable presentation of this Test results
	 * @return a string with helpful info
	 */
	// TODO improve this 
	public String toString(){
		String status = (passed() ? "OK" : "FAILED");
		String explanation = getTestType().toString() + " (expected: " + getExpected() + ", actual: " + getActual() + ")";
		return status + "<" + getID() + ">: " + explanation;
		
	}
}
